package com.liuwei.spring.cloud.common.utils.feishu;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.liuwei.spring.cloud.common.utils.Jackson;
import com.liuwei.spring.cloud.common.utils.feishu.message.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.io.File;
import java.util.*;

/**
 * @author : FeiShuHelper
 * @version V1.0
 * @date: 2023/3/2 3:14 下午
 * @Description: TODO
 */

@Slf4j
public class FeishuHelper {

    /**
     * 官方文档: https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
     */
    public static class Webhook{

        public static void sendTextMessage(String hook, String title, List<Pair<String,String>> pairs) throws Exception {
            TextMessage message = TextMessage.buildTextMessage(title,pairs);
            String response = HttpUtil.post(hook, Jackson.toJSONString(message));
            if(log.isDebugEnabled()){
                log.info("Webhook|SendTextMessage:{}",Jackson.toJSONString(message));
                log.info("Webhook|SendTextMessage:{}",response);
            }
        }

        public static void sendCardMessage(String hook, String title, String content,String buttonText,String buttonHref) throws Exception {
            CardMessage message = CardMessage.buildCardMessage(title, content,buttonText,buttonHref);
            String response = HttpUtil.post(hook, Jackson.toJSONString(message));
            if(log.isDebugEnabled()){
                log.info("Webhook|SendMarkdownMessage:{}",Jackson.toJSONString(message));
                log.info("Webhook|SendMarkdownMessage:{}",response);
            }
        }

        public static void sendRichMessage(String hook, String title, List<List<RichMessage.LineItem>> rows) throws Exception {
            RichMessage message = RichMessage.buildRichMessage(title, rows);
            String response = HttpUtil.post(hook, Jackson.toJSONString(message));
            if(log.isDebugEnabled()){
                log.info("Webhook|SendMarkdownMessage:{}",Jackson.toJSONString(message));
                log.info("Webhook|SendMarkdownMessage:{}",response);
            }
        }

        public static void sendRichMessageOfPlainText(String hook, String title, List<Pair<String,String>> pairs) throws Exception {
            List<List<RichMessage.LineItem>> lines = new ArrayList<>();
            CollectionUtils.emptyIfNull(pairs).forEach(x->{
                lines.add(Arrays.asList(new RichMessage.TextItem(StringUtils.joinWith(" ",x.getLeft(),x.getRight()))));
            });
            RichMessage message = RichMessage.buildRichMessage(title,lines);
            String response = HttpUtil.post(hook,Jackson.toJSONString(message));
            if(log.isDebugEnabled()){
                log.info("Webhook|SendMarkdownMessage:{}",Jackson.toJSONString(message));
                log.info("Webhook|SendMarkdownMessage:{}",response);
            }
        }

        public static void sendImageMessage(String hook,String token,String imageKey){
            //String token = "t-g104cthkR5MI2KRLXJAU5BTL2JROTTFTCKRPNAG6";
            //File jpg = new File("/Users/liuwei19/Samsung/gitcode/workplace/liuwei19/pic.jpg");
            //String imageKey = FeishuHelper.uploadImage(token,jpg);
            ImageMessage message = ImageMessage.buildImageMessage(imageKey);
            String response = HttpUtil.post(hook, Jackson.toJSONString(message));
            if(log.isDebugEnabled()){
                log.info("Webhook|SendMarkdownMessage:{}",Jackson.toJSONString(message));
                log.info("Webhook|SendMarkdownMessage:{}",response);
            }
        }
    }

    /**
     * 飞书获取 tenant_access_token 信息
     * tenant_access_token 的最大有效期是 2 小时。如果在有效期小于 30 分钟的情况下，调用本接口，会返回一个新的 tenant_access_token，这会同时存在两个有效的 tenant_access_token
     * https://open.feishu.cn/document/faq/trouble-shooting/how-to-choose-which-type-of-token-to-use
     * @param appId
     * @param appSecret
     * @return
     */
    public static String getTenantToken(String appId,String appSecret){
        //String appId = "cli_a504293439b1d00d";
        //String appSecret = "qRSAwujwUscwIlag9WpaYeUi8LVGYelJ";
        String url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal";
        FeishuApp.App app = new FeishuApp.App();
        app.setAppId(appId);
        app.setAppSecret(appSecret);
        String response = HttpUtil.post(url, Jackson.toJSONString(app));
        TenantTokenResponse token = Jackson.parseObject(response, TenantTokenResponse.class,true);
        return token.getToken();
    }

    /**
     * 飞书获取 app_access_token 信息
     * https://open.feishu.cn/document/server-docs/authentication-management/access-token/app_access_token_internal
     * app_access_token 的最大有效期是 2 小时。如果在有效期小于 30 分钟的情况下，调用本接口，会返回一个新的 app_access_token，这会同时存在两个有效的 app_access_token
     * @param appId
     * @param appSecret
     * @return
     */
    public static String getAppToken(String appId,String appSecret){
        //String appId = "cli_a504293439b1d00d";
        //String appSecret = "qRSAwujwUscwIlag9WpaYeUi8LVGYelJ";
        String url = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal";
        FeishuApp.App app = new FeishuApp.App();
        app.setAppId(appId);
        app.setAppSecret(appSecret);
        String response = HttpUtil.post(url, Jackson.toJSONString(app));
        AppTokenResponse token = Jackson.parseObject(response, AppTokenResponse.class,true);
        return token.getToken();
    }


    public static String uploadImage(String token,File imageFile){
        String url = "https://open.feishu.cn/open-apis/im/v1/images";
        Map<String, Object> paramMaps = new HashMap<>(4);
        paramMaps.put("image_type", "message");
        paramMaps.put("image", imageFile);
        HttpResponse response = HttpRequest.post(url)
                .header("Authorization", StrUtil.format("Bearer {}",token))
                .header("Content-Type", "multipart/form-data; boundary=---7MA4YWxkTrZu0gW")
                .form(paramMaps)
                .execute();
        int status = response.getStatus();
        String body = response.body();
        log.info("Feishu|upload:{}",body);
        ImageMessage.CodeMessage jsonObject = Jackson.parseObject(body, ImageMessage.CodeMessage.class,true);
        if(StringUtils.equalsIgnoreCase("0",jsonObject.getCode())){
            ImageMessage.UploadResponse data = Jackson.parseObject(body, ImageMessage.UploadResponse.class,true);
            return data.getData().getKey();
        }
        throw new RuntimeException(jsonObject.getMsg());
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class TenantTokenResponse {
        private String code;
        private String msg;
        @JsonProperty("tenant_access_token")
        private String token;
        private int expire;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class AppTokenResponse {
        private String code;
        private String msg;
        @JsonProperty("app_access_token")
        private String token;
        private int expire;
    }

}
